// https://www.lintcode.com/problem/valid-sudoku/

public class Solution {
    /**
     * @param board: the board
     * @return: whether the Sudoku is valid
     */
    public boolean isValidSudoku(char[][] board) {
        // write your code here
        boolean[] visited = new boolean[9];
        for (int r = 0; r < 9; ++r) { // Check by row
            clear_visited(visited);
            for (int c = 0; c < 9; ++c) {
                if (!check(board, r, c, visited)) {
                    return false;
                }
            }
        }
        for (int c = 0; c < 9; ++c) { // Check by column
            clear_visited(visited);
            for (int r = 0; r < 9; ++r) {
                if (!check(board, r, c, visited)) {
                    return false;
                }
            }
        }
        for (int block = 0; block < 9; ++block) { // Check 3*3 blocks
            clear_visited(visited);
            for (int i = 0; i < 9; ++i) {
                int r = (block / 3) * 3 + (i / 3); // Python版忘记乘3了
                int c = (block % 3) * 3 + (i % 3);
                System.out.println(block + ", " + i + ", " + r + ", " + c + ": " + board[r][c]);
                if (!check(board, r, c, visited)) {
                    return false;
                }
            }
        }
        return true;
    }
    
    private void clear_visited(boolean[] visited) {
        for (int i = 0; i < visited.length; ++i) {
            visited[i] = false;
        }
    }
    
    private boolean check(char[][] board, int r, int c, boolean[] visited) {
        char ch = board[r][c];
        if (ch != '.') {
            int idx = (int)ch - (int)'1';
            if (!visited[idx]) {
                visited[idx] = true;
                return true;
            }
            else {
                return false;
            }
        }
        return true;
    }
}